package com.pingan;

import org.springframework.util.StringUtils;

import java.io.*;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;


public class ScannerUtil {

    public void scan(String projectPath) throws FileNotFoundException {
        String currentDir = System.getProperty("user.dir");
        File file = new File(currentDir);
        if (file.isDirectory()) {
            File childFile = new File(projectPath + "\\" + file.getName());
            String fileNameSuffix = childFile.getName().split(".")[1].toLowerCase();
            //暂时只处理ssm war 包场景，暂未处理 springBoot 场景
            if ("war".equals(file)) {

            }
        }
    }

    public void resolvingJar() throws IOException {
        List<FileInfo> list = new ArrayList<>();
        File file = new File("D:\\test\\lib");
        File[] files = file.listFiles();

        for (File jar : files) {
            //System.out.println("jar: " + jar.getName());
            JarFile jarFile = new JarFile(jar);
            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry jarEntry = entries.nextElement();
                if (jarEntry != null) {
                    String className = jarEntry.getName();
                    if (className.endsWith("class")) {
                        String classComspec = className.split("\\.")[0].replaceAll("/", ".");
                        FileInfo fileInfo = new FileInfo(classComspec, jar.getName());
                        list.add(fileInfo);
                    }
                }
            }
        }

        Map<String, Set<String>> conflictClass = findConflictClass(list);
        printConflictToText(conflictClass);
    }


    public Map<String, Set<String>> findConflictClass(List<FileInfo> list) {
        Map<String, Set<String>> conflictMap = new HashMap<>();
        //寻找包里边类全限定名称一样的
        for (int i = 0; i < list.size(); i++) {
            FileInfo fileInfo = list.get(i);
            String comspec = fileInfo.getComspec().trim();

            Set<String> conflictJars;
            if (conflictMap.containsKey(comspec)) {
                conflictJars = conflictMap.get(comspec);
            } else {
                conflictJars = new HashSet<>();
            }

            for (int j = list.size() - 1; j >= i; j--) {
                String nextComspec = list.get(j).getComspec().trim();
                if (!StringUtils.isEmpty(comspec) && !StringUtils.isEmpty(nextComspec)) {
                    if (comspec.equals(nextComspec)) {
                        conflictJars.add(fileInfo.getJarName());
                    }
                }
            }
            conflictMap.put(comspec, conflictJars);
        }
        return conflictMap;
    }

    public void printConflictToText(Map<String, Set<String>> conflictMap) {
        for (String comspec : conflictMap.keySet()) {
            Set<String> list = conflictMap.get(comspec);
            if (list.size() > 1) {
                System.out.println(comspec);
                for (String jarName : list) {
                    System.out.println("  == " + jarName);
                }
            }

        }
    }


    public void copyScanWar(String projectPath) throws Exception {
        //读取war 包

        JarFile file = new JarFile(projectPath);
        Enumeration<JarEntry> entries = file.entries();

        while (entries.hasMoreElements()) {
            JarEntry jarEntry = entries.nextElement();
            String fileName = jarEntry.getName();
            //获取所有的jar
            if (fileName.startsWith("WEB-INF/lib/") && fileName.endsWith("jar")) {
                System.out.println("fileName :" + fileName);
                InputStream in = file.getInputStream(jarEntry);
                /*JarInputStream jarStream = new JarInputStream(in);*/
                String jarName = interceptJarName(fileName);
                doZipFile(in, jarName);
            }
        }
    }

    /*private void analyzingClass(JarEntry entry) {
        if (!entry.isDirectory()) {
            System.out.println("文件：" + entry.getName());
        } else {
            //todo 递归遍历所有文件夹内的class 文件
            System.out.println("文件夹entry: " + entry);
        }
    }*/

    public String interceptJarName(String fileName) {
        String[] split = null;
        if (fileName != null && fileName.length() > 0) {
            split = fileName.split("/");

        }
        return split[split.length - 1];
    }

    public void doZipFile(InputStream in, String jarName) {
        String jarDir = createAndReturnZipDir();
        OutputStream os = null;

        byte[] data = new byte[1024];
        try {
            os = new FileOutputStream(jarDir + "\\" + jarName);
            while ((in.read(data)) != -1) {
                os.write(data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                System.out.println("io close exception");
            }
        }

    }

    public String createAndReturnZipDir() {
        String currentDir = System.getProperty("user.dir");
        File jarDir = new File(currentDir + "\\lib");
        if (!jarDir.exists()) {
            jarDir.mkdir();
        }
        return jarDir.getPath();
    }


    public static void main(String[] args) throws Exception {
        ScannerUtil scannerUtil = new ScannerUtil();
        //String s = scannerUtil.interceptJarName("WEB-INF/lib/spring-webmvc-4.2.5.RELEASE.jar");
        //System.out.println(s);
       /* scannerUtil.copyScanWar("D:\\test\\seckill.war");*/
        // scannerUtil.copyScanWar("F:\\java 资料\\matching-plugin\\seckill.war");
        //F:\java 资料\matching-plugin\lib
        //scannerUtil.resolvingJar();
        System.out.println("开始扫描========");
        scannerUtil.resolvingJar();
        System.out.println("结束扫描========");
        /*String name = "org/codehaus/mojo/animal_sniffer/IgnoreJRERequirement.class";
        String[] str = name.split("\\.");
        System.out.println(name.split("\\.")[0].replaceAll("/", "."));*/
       /* mp();*/
    }

    public static void mp() {
        int[] in = new int[]{3, 5, 1, 9, 7, 2};
        for (int i = 0; i < in.length; i++) {
            for (int j = in.length - 1; j >= i; j--) {
                if (in[i] > in[j]) {
                    int zz = in[j];
                    in[j] = in[i];
                    in[i] = zz;
                }
            }
        }

        System.out.println(in);
    }


}
